﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FBroSharp;
using FBroSharp.Lib;
using FBroSharp.Value;
using FBroSharp.Const;
using FBroSharp.DataType;

namespace HTTP请求拦截器
{
    public partial class Form1 : Form
    {
        private const string BROWSER_USER_FLAG = "http_interceptor_browser";
        private List<HttpRequestInfo> _httpRequests = new List<HttpRequestInfo>();
        private string _logFilePath;

        public Form1()
        {
            InitializeComponent();
            InitializeLogFile();
        }

        private void InitializeLogFile()
        {
            string logDir = Path.Combine(Directory.GetCurrentDirectory(), "Logs");
            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }
            _logFilePath = Path.Combine(logDir, $"http_log_{DateTime.Now:yyyyMMdd_HHmmss}.txt");
            File.WriteAllText(_logFilePath, $"HTTP请求拦截日志 - {DateTime.Now}\r\n");
            File.AppendAllText(_logFilePath, new string('=', 80) + "\r\n\r\n");
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 创建浏览器
            CreateBrowser();
        }

        private void CreateBrowser()
        {
            try
            {
                // 创建窗口信息
                FBroSharpWindowsInfo windows_info = new FBroSharpWindowsInfo
                {
                    parent_window = panelBrowser.Handle,
                    x = 0,
                    y = 0,
                    width = panelBrowser.Width,
                    height = panelBrowser.Height,
                    window_name = "HTTP请求拦截器"
                };

                // 创建浏览器事件回调
                BrowserEvent browser_event = new BrowserEvent(this);

                // 创建浏览器
                if (FBroSharpControl.CreatBrowser(
                    "https://www.baidu.com", 
                    windows_info, 
                    default, 
                    default, 
                    default, 
                    browser_event, 
                    default, 
                    BROWSER_USER_FLAG))
                {
                    UpdateStatus("浏览器创建成功");
                    Console.WriteLine("✅ 浏览器创建成功");
                }
                else
                {
                    UpdateStatus("浏览器创建失败");
                    MessageBox.Show("浏览器创建失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"创建浏览器异常: {ex.Message}");
                MessageBox.Show($"创建浏览器异常: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            ResizeEmbeddedBrowser();
        }

        private void ResizeEmbeddedBrowser()
        {
            try
            {
                var browser = FBroSharpBrowserListControl.GetBrowserFromFlag(BROWSER_USER_FLAG);
                if (browser != null && browser.IsValid)
                {
                    browser.MoveWindow(0, 0, panelBrowser.Width, panelBrowser.Height, true);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"调整浏览器大小失败: {ex.Message}");
            }
        }

        private void btnNavigate_Click(object sender, EventArgs e)
        {
            NavigateToUrl(txtUrl.Text);
        }

        private void txtUrl_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                NavigateToUrl(txtUrl.Text);
                e.SuppressKeyPress = true;
            }
        }

        private void NavigateToUrl(string url)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(url))
                {
                    UpdateStatus("请输入URL地址");
                    return;
                }

                // 自动添加http://前缀
                if (!url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) &&
                    !url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
                {
                    url = "http://" + url;
                }

                var browser = FBroSharpBrowserListControl.GetBrowserFromFlag(BROWSER_USER_FLAG);
                if (browser != null && browser.IsValid)
                {
                    var frame = browser.GetMainFrame();
                    if (frame != null && frame.IsValid)
                    {
                        frame.LoadURL(url);
                        UpdateStatus($"正在导航到: {url}");
                    }
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"导航失败: {ex.Message}");
                MessageBox.Show($"导航失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnBack_Click(object sender, EventArgs e)
        {
            try
            {
                var browser = FBroSharpBrowserListControl.GetBrowserFromFlag(BROWSER_USER_FLAG);
                if (browser != null && browser.IsValid)
                {
                    if (browser.CanGoBack())
                    {
                        browser.GoBack();
                    }
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"后退失败: {ex.Message}");
            }
        }

        private void btnForward_Click(object sender, EventArgs e)
        {
            try
            {
                var browser = FBroSharpBrowserListControl.GetBrowserFromFlag(BROWSER_USER_FLAG);
                if (browser != null && browser.IsValid)
                {
                    if (browser.CanGoForward())
                    {
                        browser.GoForward();
                    }
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"前进失败: {ex.Message}");
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            try
            {
                var browser = FBroSharpBrowserListControl.GetBrowserFromFlag(BROWSER_USER_FLAG);
                if (browser != null && browser.IsValid)
                {
                    browser.Reload();
                    UpdateStatus("刷新页面");
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"刷新失败: {ex.Message}");
            }
        }

        private void btnClearLog_Click(object sender, EventArgs e)
        {
            _httpRequests.Clear();
            listViewRequests.Items.Clear();
            txtResponseDetails.Clear();
            UpdateStatus($"日志已清除 (共清除 {_httpRequests.Count} 条记录)");
        }

        private void btnExportLog_Click(object sender, EventArgs e)
        {
            try
            {
                SaveFileDialog saveDialog = new SaveFileDialog
                {
                    Filter = "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*",
                    FileName = $"http_export_{DateTime.Now:yyyyMMdd_HHmmss}.txt"
                };

                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine($"HTTP请求拦截导出 - {DateTime.Now}");
                    sb.AppendLine(new string('=', 80));
                    sb.AppendLine($"总请求数: {_httpRequests.Count}");
                    sb.AppendLine();

                    foreach (var req in _httpRequests)
                    {
                        sb.AppendLine($"时间: {req.Timestamp:yyyy-MM-dd HH:mm:ss.fff}");
                        sb.AppendLine($"方法: {req.Method}");
                        sb.AppendLine($"状态: {req.StatusCode}");
                        sb.AppendLine($"类型: {req.MimeType}");
                        sb.AppendLine($"URL: {req.Url}");
                        if (req.ResponseData != null)
                        {
                            sb.AppendLine($"大小: {req.ResponseData.Length} 字节");
                        }
                        sb.AppendLine(new string('-', 80));
                    }

                    File.WriteAllText(saveDialog.FileName, sb.ToString(), Encoding.UTF8);
                    UpdateStatus($"日志已导出到: {saveDialog.FileName}");
                    MessageBox.Show($"日志已成功导出到:\n{saveDialog.FileName}", "导出成功", 
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"导出失败: {ex.Message}");
                MessageBox.Show($"导出失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void txtSearch_TextChanged(object sender, EventArgs e)
        {
            FilterRequests();
        }

        private void FilterRequests()
        {
            string searchText = txtSearch.Text.Trim().ToLower();
            
            listViewRequests.Items.Clear();

            var filteredRequests = string.IsNullOrEmpty(searchText) 
                ? _httpRequests 
                : _httpRequests.Where(r => 
                    r.Url.ToLower().Contains(searchText) || 
                    r.Method.ToLower().Contains(searchText) ||
                    r.MimeType.ToLower().Contains(searchText)).ToList();

            foreach (var req in filteredRequests)
            {
                AddRequestToListView(req);
            }
        }

        private void listViewRequests_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listViewRequests.SelectedItems.Count > 0)
            {
                int index = (int)listViewRequests.SelectedItems[0].Tag;
                ShowRequestDetails(index);
            }
        }

        private void ShowRequestDetails(int index)
        {
            if (index >= 0 && index < _httpRequests.Count)
            {
                var req = _httpRequests[index];
                StringBuilder sb = new StringBuilder();
                
                sb.AppendLine($"时间: {req.Timestamp:yyyy-MM-dd HH:mm:ss.fff}");
                sb.AppendLine($"方法: {req.Method}");
                sb.AppendLine($"状态码: {req.StatusCode}");
                sb.AppendLine($"内容类型: {req.MimeType}");
                sb.AppendLine($"URL: {req.Url}");
                sb.AppendLine();
                sb.AppendLine("响应数据:");
                sb.AppendLine(new string('-', 80));
                
                if (req.ResponseData != null && req.ResponseData.Length > 0)
                {
                    sb.AppendLine($"大小: {req.ResponseData.Length} 字节");
                    sb.AppendLine();
                    
                    // 尝试显示文本内容
                    try
                    {
                        string content = Encoding.UTF8.GetString(req.ResponseData);
                        if (content.Length > 10000)
                        {
                            sb.AppendLine(content.Substring(0, 10000));
                            sb.AppendLine();
                            sb.AppendLine($"... (已截断，仅显示前10000字符，总共{content.Length}字符)");
                        }
                        else
                        {
                            sb.AppendLine(content);
                        }
                    }
                    catch
                    {
                        sb.AppendLine("[二进制数据，无法显示为文本]");
                    }
                }
                else
                {
                    sb.AppendLine("[无响应数据]");
                }
                
                txtResponseDetails.Text = sb.ToString();
            }
        }

        #region 从BrowserEvent调用的公共方法

        public void UpdateStatus(string message)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateStatus(message)));
                return;
            }
            lblStatus.Text = message;
        }

        public void UpdateAddressBar(string url)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateAddressBar(url)));
                return;
            }
            txtUrl.Text = url;
        }

        public void UpdateTitle(string title)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateTitle(title)));
                return;
            }
            this.Text = $"HTTP请求拦截器 - {title}";
        }

        public void UpdateNavigationButtons(bool canGoBack, bool canGoForward, bool isLoading)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateNavigationButtons(canGoBack, canGoForward, isLoading)));
                return;
            }
            btnBack.Enabled = canGoBack;
            btnForward.Enabled = canGoForward;
            btnRefresh.Enabled = !isLoading;
        }

        public void LogHttpRequest(HttpRequestInfo requestInfo)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => LogHttpRequest(requestInfo)));
                return;
            }

            requestInfo.Index = _httpRequests.Count;
            _httpRequests.Add(requestInfo);
            
            AddRequestToListView(requestInfo);

            // 写入日志文件
            WriteToLogFile(requestInfo, null);
        }

        public void LogHttpResponse(string url, string method, byte[] responseData)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => LogHttpResponse(url, method, responseData)));
                return;
            }

            // 查找对应的请求
            var request = _httpRequests.LastOrDefault(r => r.Url == url && r.Method == method);
            if (request != null)
            {
                request.ResponseData = responseData;
                
                // 更新ListView中的大小列
                foreach (ListViewItem item in listViewRequests.Items)
                {
                    if ((int)item.Tag == request.Index)
                    {
                        item.SubItems[5].Text = FormatFileSize(responseData.Length);
                        break;
                    }
                }

                // 写入响应数据到日志
                WriteToLogFile(request, responseData);
            }
        }

        #endregion

        private void AddRequestToListView(HttpRequestInfo requestInfo)
        {
            ListViewItem item = new ListViewItem(requestInfo.Timestamp.ToString("HH:mm:ss.fff"));
            item.SubItems.Add(requestInfo.Method);
            item.SubItems.Add(requestInfo.StatusCode.ToString());
            item.SubItems.Add(requestInfo.MimeType);
            item.SubItems.Add(requestInfo.Url);
            item.SubItems.Add(requestInfo.ResponseData != null ? FormatFileSize(requestInfo.ResponseData.Length) : "-");
            item.Tag = requestInfo.Index;
            
            listViewRequests.Items.Add(item);
            
            // 自动滚动到最新项
            item.EnsureVisible();
        }

        private void WriteToLogFile(HttpRequestInfo requestInfo, byte[] responseData)
        {
            try
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine($"[{requestInfo.Timestamp:yyyy-MM-dd HH:mm:ss.fff}]");
                sb.AppendLine($"方法: {requestInfo.Method}");
                sb.AppendLine($"状态: {requestInfo.StatusCode}");
                sb.AppendLine($"类型: {requestInfo.MimeType}");
                sb.AppendLine($"URL: {requestInfo.Url}");
                
                if (responseData != null)
                {
                    sb.AppendLine($"大小: {responseData.Length} 字节 ({FormatFileSize(responseData.Length)})");
                }
                
                sb.AppendLine(new string('-', 80));
                sb.AppendLine();
                
                File.AppendAllText(_logFilePath, sb.ToString(), Encoding.UTF8);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"写入日志文件失败: {ex.Message}");
            }
        }

        private string FormatFileSize(long bytes)
        {
            string[] sizes = { "B", "KB", "MB", "GB" };
            double len = bytes;
            int order = 0;
            while (len >= 1024 && order < sizes.Length - 1)
            {
                order++;
                len = len / 1024;
            }
            return $"{len:0.##} {sizes[order]}";
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                var browser = FBroSharpBrowserListControl.GetBrowserFromFlag(BROWSER_USER_FLAG);
                if (browser != null && browser.IsValid)
                {
                    browser.CloseBrowser(false, false);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"关闭浏览器失败: {ex.Message}");
            }
        }
    }

    /// <summary>
    /// HTTP请求信息类
    /// </summary>
    public class HttpRequestInfo
    {
        public int Index { get; set; }
        public string Url { get; set; }
        public string Method { get; set; }
        public int StatusCode { get; set; }
        public string MimeType { get; set; }
        public DateTime Timestamp { get; set; }
        public byte[] ResponseData { get; set; }
    }
}
